package com.example.user.customviewdemo.drawing.bessel;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

/**
 * 义无反顾地追逐梦想
 * Created by user on 2016/4/25.
 * 贝塞尔曲线即path中的quato函数就是一个二阶贝塞尔曲线，可用于手势轨迹和充电水波纹效果
 */
public class MyBesselView extends View{
    private Path path = new Path();
    private Path path1 = new Path();
    private float mPreX,mPreY;
    private float dx,dy;
    private float waveLenth = 1000;
    private float orgX = -1000;
    private float orgY=  800;
    private Paint paint;

    private Context context;

    public MyBesselView(Context context) {
        super(context);
    }

    public MyBesselView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);

    }

    public MyBesselView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                path.moveTo(event.getX(),event.getY());
                mPreX = event.getX();
                mPreY = event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
               // path.lineTo(event.getX(),event.getY());用lineto直线绘制手势轨迹，但不平滑 下面使用quato来绘制
                float x = (mPreX + event.getX()) / 2;
                float y = (mPreY + event.getY()) / 2;

                path.quadTo(mPreX,mPreY,x,y);
                mPreX = event.getX();
                mPreY = event.getY();

                postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLACK);
        path1.reset();//表示path重置，又是一个新的path,一定要添加该方法，不然会出现意想不到的结果


        canvas.drawPath(path,paint);//绘制手势图

        /**
         * 二阶贝塞尔使用总结:三个点可以构成一条二阶贝塞尔曲线，一个起点，一个楚控点，一个终点
         * 1、path.moveto(float x,float y);该点表示起点，若不指定，则默认（0,0）为起点
         * 2、path.quato(float x1,float y1,float x2,float y2);(x1,y1)为触控点，(x2,y2)为终点
         * 3、若在quato后面再使用path.quato(float x3,float y4,float x5,float y5),则这次的起点为上次的终点即上面的（x2,y2）
         * 4、path.rQuato(float dx1,float dy1,float dx2,float dy2 )该方法中所有参数表示相对起点的坐标
         * 5、同理若后面继续使用rQuato（）则是相对前一条贝塞尔曲线的终点的相对坐标
         *
         * 比如，我们上一个终点坐标是(300,400)那么利用rQuadTo(100,-100,200,100)；
         * 得到的控制点坐标是（300+100,400-100）即(500,300)
         * 同样，得到的终点坐标是(300+200,400+100)即(500,500)
         */

        //满屏绘制波浪，并且左边超出一个波长
        path1.moveTo(orgX + dx,orgY);
        for (float i = -waveLenth;i<getWidth()+waveLenth;i+=waveLenth){
            path1.rQuadTo(waveLenth/4,-100 + dy,waveLenth/2,0);
            path1.rQuadTo(waveLenth/4,100 + dy,waveLenth/2,0);
        }
        path1.lineTo(getWidth(),getHeight());
        path1.lineTo(0,getHeight());
        path1.close();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.GREEN);

        canvas.drawPath(path1,paint);
    }

    /**
     * 启动动画
     */
    public void startAnimator(){
        final ValueAnimator animator1 = ValueAnimator.ofFloat(0,waveLenth);
        animator1.setInterpolator(new LinearInterpolator());
        animator1.setDuration(2000);
        animator1.setRepeatCount(100);
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                dx = (float) animator1.getAnimatedValue();
                postInvalidate();
            }
        });
        animator1.start();
        final ValueAnimator animator2 = ValueAnimator.ofFloat(0,-50,0,50,0);
        animator2.setInterpolator(new LinearInterpolator());
        animator2.setDuration(2000);
        animator1.setRepeatCount(100);
        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                dy = (float) animator2.getAnimatedValue();
                postInvalidate();
            }
        });
        animator2.start();
    }

}
